/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { createFile, createNamespace, IDLEntry, IDLFile, IDLInterface, isDefined, isInterface, isNamespace, linearizeNamespaceMembers, linkParentBack } from "@idlizer/core";

export abstract class Transformer {
    constructor(protected file: IDLFile, private removeNamespaces: boolean = false) {}

    transformFile(input: IDLFile): IDLFile {
        let entries: IDLEntry[] = this.removeNamespaces ?
            linearizeNamespaceMembers(input.entries).filter(it => !isNamespace(it)) : input.entries
        let file = createFile(entries
            .map(it => this.transformDeep(it))
            .filter(isDefined),
            input.fileName)
        linkParentBack(file)
        return file
    }
    transformDeep(entry: IDLEntry): IDLEntry | undefined {
        if (isNamespace(entry)) {
            return createNamespace(entry.name,
                entry.members
                    .map(it => this.transformDeep(it))
                    .filter(isDefined)
                )
        }
        return this.transform(entry)
    }

    transform(entry: IDLEntry): IDLEntry | undefined {
        if  (isInterface(entry))
            return this.transformInterface(entry)
        else
            return entry
    }

    transformed(): IDLFile {
        return this.transformFile(this.file)
    }
    abstract transformInterface(entry: IDLInterface): IDLEntry | undefined
}